#include "CConfigParser.h"

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "CStringUtils.h"

CConfigParser* CConfigParser::m_pInstance = nullptr;

CConfigParser::CConfigParser()
{

}

bool CConfigParser::load(const char* lpConfFile)
{
    FILE* fp = fopen(lpConfFile, "r");
    if (fp == nullptr) {
        return false;
    }

    char szLineBuf[501];

    while (!feof(fp)) {
        memset(szLineBuf, 0, sizeof(szLineBuf));
        if (fgets(szLineBuf, 500, fp) == nullptr) {
            continue;
        }

        if (szLineBuf[0] == 0) {
            continue;
        }

        if (*szLineBuf == ';' || *szLineBuf == ' ' || *szLineBuf == '#' ||
            *szLineBuf == '\t' || *szLineBuf == '\n') {
            continue;
        }

    procLineBuf:
        if (strlen(szLineBuf) > 0) {
            char chEndOfLine = szLineBuf[strlen(szLineBuf) - 1];
            if (chEndOfLine == 10 || chEndOfLine == 13 || chEndOfLine == 32) {
                szLineBuf[strlen(szLineBuf) - 1] = 0;
                goto procLineBuf;
            }
        }

        if (szLineBuf[0] == 0) {
            continue;
        }

        if (*szLineBuf == '[') {
            continue;
        }

        char* pszTmp = strchr(szLineBuf, '=');
        if (nullptr != pszTmp) {
            LPConfigItem pConfigItem = new CConfigItem;
            memset(pConfigItem, 0, sizeof(CConfigItem));
            strncpy(pConfigItem->szItemName, szLineBuf, (int)(pszTmp - szLineBuf));
            strcpy(pConfigItem->szItemContent, pszTmp + 1);

            CStringUtils::rTrim(pConfigItem->szItemName);
            CStringUtils::lTrim(pConfigItem->szItemName);
            CStringUtils::rTrim(pConfigItem->szItemContent);
            CStringUtils::lTrim(pConfigItem->szItemContent);

            m_vecConfigItem.push_back(pConfigItem);
        }
    }

    fclose(fp);
    return true;
}

const char* CConfigParser::getString(const char* lpItemName)
{
    for (auto pos = m_vecConfigItem.begin(); pos != m_vecConfigItem.end(); ++pos)
    {
        if (strcasecmp((*pos)->szItemName, lpItemName) == 0) {
            return (*pos)->szItemContent;
        }
    }

    return nullptr;
}

int CConfigParser::getIntDefault(const char* lpItemName, const int iDefaultVal)
{
    for (auto pos = m_vecConfigItem.begin(); pos != m_vecConfigItem.end(); ++pos)
    {
        if (strcasecmp((*pos)->szItemName, lpItemName) == 0) {
            return atoi((*pos)->szItemContent);
        }
    }
    return iDefaultVal;
}

bool CConfigParser::getBoolDefault(const char* lpItemName, const int iDefaultVal)
{
    return getIntDefault(lpItemName, iDefaultVal) != 0;
}

CConfigParser::~CConfigParser()
{
    for (auto it = m_vecConfigItem.begin(); it != m_vecConfigItem.end(); ++it) {
        delete (*it);
    }
    m_vecConfigItem.clear();
}